package br.edu.utfpr.controller.interfaces;
import java.util.List;

import br.edu.utfpr.controller.validator.RetornoValidacao;
import br.edu.utfpr.controller.validator.Validator;
import br.edu.utfpr.dao.interfaces.Dao;
import br.edu.utfpr.sgbd.HibernateUtil;
import br.edu.utfpr.util.IBean;


public class AbstractController<Bean extends IBean, Validator_ extends Validator<Bean>, D extends Dao<Bean>>
{
	protected D dao;
	protected Validator<Bean> validator;
	
	public AbstractController(D dao, Validator<Bean> validator)
	{
		this.dao = dao;
		this.validator = validator;
		assertDaoAndValidator();
	}
	
	public AbstractController()
	{
		super();
	}
	
	/**
	 * Salva um objeto e commita.
	 * 
	 * @param bean
	 */
	public RetornoValidacao save(Bean bean)
	{	
		assertDtoNotNull(bean);
		assertDaoAndValidator();
	
		RetornoValidacao rv = validator.isValido(bean);
		if(!rv.isOk())
		{
			return rv;
		}
		
		try
		{
			dao.save(bean);
			return new RetornoValidacao();
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return new RetornoValidacao("Desculpe, ocorreu um erro desconhecido.");
		}
	}
	
	/**
	 * Exclui um objeto e commita.
	 * 
	 * @param bean
	 */
	public void excluir(Bean bean)
	{
		assertDtoNotNull(bean);
		assertDaoAndValidator();
		dao.delete(bean);
	}
	
	/**
	 * Lista todos.
	 * 
	 * @return
	 */
	public List<Bean> list()
	{
		assertDaoAndValidator();
		List<Bean> list = dao.list();
		return list;
	}
	
	/**
	 * Carrega o objeto atual.
	 * 
	 * @param id
	 * @return
	 */
	public Bean load(Long id)
	{
		assertDaoAndValidator();
		Bean bean = dao.load(id);
		return bean;
	}
	
	/**
	 * Asserta que o objeto nao esteja null.
	 * 
	 * @param bean
	 */
	private void assertDtoNotNull(Bean bean)
	{
		assert bean != null : "o objeto a ser salvo deve ser um objeto valido";
	}
	
	private void assertDaoAndValidator()
	{
		assert dao != null : "o dao esta null, algo de errado deu errado, manolo!";
		assert validator != null : "o validator veio null, verifique!";
	}
	
	private void commitTransaction()
	{
		HibernateUtil.getInstance().commitTransaction();
	}
	
	private void rollbackTransaction()
	{
		HibernateUtil.getInstance().rollbackTransaction();
	}
	
	protected void beginTransaction()
	{
		HibernateUtil.getInstance().beginTransaction();
	}
}
